﻿// Decompiled with JetBrains decompiler
// Type: Netick.Unity.NetickUnityMismatchChecker
// Assembly: Netick.Unity, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: E128C7FD-39ED-4452-86AC-6EC748457030
// Assembly location: D:\WorkSpaceDemo\UPM\NetickForUnity\Netick\Runtime\Netick.Unity.dll
// XML documentation location: D:\WorkSpaceDemo\UPM\NetickForUnity\Netick\Runtime\Netick.Unity.xml

using System;

#nullable disable
namespace Netick.Unity;

internal sealed class NetickUnityMismatchChecker : MismatchChecker
{
  private readonly NetworkSandbox Sandbox;
  private readonly int SizeWords;
  private int Version;
  private int ConfigHash;

  private unsafe ProjectMatchingData ProjectVersionData => *(ProjectMatchingData*) this.StatePtr;

  public NetickUnityMismatchChecker(NetworkSandbox sandbox, NetickEngine engine)
    : base(engine)
  {
    this.Sandbox = sandbox;
    this.SizeWords = NetickUtils.GetWordSize(sizeof (ProjectMatchingData));
  }

  public override unsafe void Reset()
  {
    for (int index = 0; index < this.SizeWords; ++index)
      this.StatePtr[index] = 0;
    this.ConfigHash = this.Engine.Config.GetNetworkHashCode();
    this.ConfigHash = this.ConfigHash * 31 /*0x1F*/ + this.Sandbox.Config.MaxAdditiveScenes;
    this.ConfigHash = this.ConfigHash * 31 /*0x1F*/ + (this.Sandbox.Config.SyncTransformOnSpawn ? 1 : 0);
    this.ConfigHash = this.ConfigHash * 31 /*0x1F*/ + (this.Sandbox.Config.IncludeInactiveObjects ? 1 : 0);
    this.Version = Convert.ToInt32("0.14.73".Replace(".", string.Empty));
    if (this.Engine.IsClient)
      return;
    int* numPtr = (int*) &new ProjectMatchingData()
    {
      NetickVersion = this.Version,
      NetickConfigHash = this.ConfigHash,
      PrefabsLength = this.Sandbox.GlobalPrefabs.Count,
      CustomScenesLength = this.Sandbox.NetworkSceneHandler.CustomScenesCount
    };
    int* statePtr = this.StatePtr;
    for (int index = 0; index < this.SizeWords; ++index)
    {
      int* p = statePtr + index;
      if (numPtr[index] != *p)
        this.MarkAltered(p);
      *p = numPtr[index];
    }
  }

  private int CalcPrefabStateSizeHash()
  {
    int num = 17;
    for (int index = 0; index < this.Sandbox.GlobalPrefabs.Count; ++index)
      num = num * 31 /*0x1F*/ + this.Sandbox.GlobalPrefabs[index].CalcPrefabSizeWords(this.Sandbox);
    return num;
  }

  public override int GetSizeWords() => this.SizeWords;

  public override void PostReadPhase1() => this.TryDetectMismatches();

  private void TryDetectMismatches()
  {
    if (this.ConfigHash != this.ProjectVersionData.NetickConfigHash)
      throw new Mismatch("Netick configuration mismatch: Please ensure that Netick settings are consistent across all clients and the server.");
    if (this.Version != this.ProjectVersionData.NetickVersion)
      throw new Mismatch($"Netick version mismatch: Expected {this.ProjectVersionData.NetickVersion}, but found {this.Version}. Please ensure that all clients and the server are using the same version of Netick.");
    if (this.Sandbox.GlobalPrefabs.Count != this.ProjectVersionData.PrefabsLength)
      throw new Mismatch($"Prefab list count mismatch: Expected {this.ProjectVersionData.PrefabsLength}, but found {this.Sandbox.GlobalPrefabs.Count}. Please ensure that all clients and the server have the same prefab list.");
    if (this.Sandbox.NetworkSceneHandler.CustomScenesCount != this.ProjectVersionData.CustomScenesLength)
      throw new Mismatch($"Custom scenes count mismatch: Expected {this.ProjectVersionData.CustomScenesLength}, but found {this.Sandbox.NetworkSceneHandler.CustomScenesCount}. Please ensure that all clients and the server have the same custom scenes.");
  }
}
